package com.wstuo.common.rules.entity;

import com.wstuo.common.entity.BaseEntity;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapKeyColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * bean of rule
 * 
 * @author <a href="mailto:376890523@qq.com">Wstuo</a>
 * @version 0.1 2010.9.28
 */
@SuppressWarnings({ "serial", "rawtypes" })
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "T_Rule")
public class Rule extends BaseEntity {
	/**
	 * rule no
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long ruleNo;

	/**
	 * rule name
	 */
	private String ruleName;

	/**
	 * dialect
	 */
	private String dialect;

	/**
	 * version number
	 */
	private Long versionNumber=0L;

	/**
	 * whether disabled
	 */
	private Boolean disabled=false;

	/**
	 * package
	 */
	@ManyToOne
	@JoinColumn(name = "rulePackageNo")
	private RulePackage rulePackage;

	/**
	 * map of attributes
	 */
	@ElementCollection
	@MapKeyColumn(name = "attrName", nullable = false)
	@CollectionTable(name = "ruleAttr")
	@Column(name = "attr")
	private Map<String, String> attr = new HashMap<String, String>();

	/**
	 * list of pattern
	 */
	@OneToOne(cascade = CascadeType.ALL)
	private RulePattern condition;

	/**
	 * list of action
	 */
	@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "rule")
	private List<RuleAction> actions = new ArrayList<RuleAction>();
	private Long salience;// 匹配顺序

	public RulePackage getRulePackage() {
		return rulePackage;
	}

	public void setRulePackage(RulePackage rulePackage) {
		this.rulePackage = rulePackage;
	}

	public RulePattern getCondition() {
		return condition;
	}

	public void setCondition(RulePattern condition) {
		this.condition = condition;
	}

	public List<RuleAction> getActions() {
		return actions;
	}

	public void setActions(List<RuleAction> actions) {
		this.actions = actions;
	}

	public Long getRuleNo() {
		return ruleNo;
	}

	public void setRuleNo(Long ruleNo) {
		this.ruleNo = ruleNo;
	}

	public String getRuleName() {
		return ruleName;
	}

	public void setRuleName(String ruleName) {
		this.ruleName = ruleName;
	}

	public String getDialect() {
		return dialect;
	}

	public void setDialect(String dialect) {
		this.dialect = dialect;
	}

	public Long getVersionNumber() {
		return versionNumber;
	}

	public void setVersionNumber(Long versionNumber) {
		this.versionNumber = versionNumber;
	}

	public Boolean getDisabled() {
		return disabled;
	}

	public void setDisabled(Boolean disabled) {
		this.disabled = disabled;
	}

	public Map<String, String> getAttr() {
		return attr;
	}

	public void setAttr(Map<String, String> attr) {
		this.attr = attr;
	}

	public Rule() {

	}

	public Rule(Long ruleNo, String ruleName, String dialect,
			Long versionNumber, Boolean disabled, RulePackage rulePackage,
			Map<String, String> attr, RulePattern condition,
			List<RuleAction> actions) {
		super();
		this.ruleNo = ruleNo;
		this.ruleName = ruleName;
		this.dialect = dialect;
		this.versionNumber = versionNumber;
		this.disabled = disabled;
		this.rulePackage = rulePackage;
		this.attr = attr;
		this.condition = condition;
		this.actions = actions;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((actions == null) ? 0 : actions.hashCode());
		result = prime * result + ((attr == null) ? 0 : attr.hashCode());
		result = prime * result
				+ ((condition == null) ? 0 : condition.hashCode());
		result = prime * result + ((dialect == null) ? 0 : dialect.hashCode());
		result = prime * result
				+ ((disabled == null) ? 0 : disabled.hashCode());
		result = prime * result
				+ ((ruleName == null) ? 0 : ruleName.hashCode());
		result = prime * result + ((ruleNo == null) ? 0 : ruleNo.hashCode());
		result = prime * result
				+ ((rulePackage == null) ? 0 : rulePackage.hashCode());
		result = prime * result
				+ ((salience == null) ? 0 : salience.hashCode());
		result = prime * result
				+ ((versionNumber == null) ? 0 : versionNumber.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Rule other = (Rule) obj;
		if (actions == null) {
			if (other.actions != null)
				return false;
		} else if (!actions.equals(other.actions))
			return false;
		if (attr == null) {
			if (other.attr != null)
				return false;
		} else if (!attr.equals(other.attr))
			return false;
		if (condition == null) {
			if (other.condition != null)
				return false;
		} else if (!condition.equals(other.condition))
			return false;
		if (dialect == null) {
			if (other.dialect != null)
				return false;
		} else if (!dialect.equals(other.dialect))
			return false;
		if (disabled == null) {
			if (other.disabled != null)
				return false;
		} else if (!disabled.equals(other.disabled))
			return false;
		if (ruleName == null) {
			if (other.ruleName != null)
				return false;
		} else if (!ruleName.equals(other.ruleName))
			return false;
		if (ruleNo == null) {
			if (other.ruleNo != null)
				return false;
		} else if (!ruleNo.equals(other.ruleNo))
			return false;
		if (rulePackage == null) {
			if (other.rulePackage != null)
				return false;
		} else if (!rulePackage.equals(other.rulePackage))
			return false;
		if (salience == null) {
			if (other.salience != null)
				return false;
		} else if (!salience.equals(other.salience))
			return false;
		if (versionNumber == null) {
			if (other.versionNumber != null)
				return false;
		} else if (!versionNumber.equals(other.versionNumber))
			return false;
		return true;
	}

	public Long getSalience() {
		return salience;
	}

	public void setSalience(Long salience) {
		this.salience = salience;
	}
	
	public List<RuleConstraint> getConstraints(){
		return condition.getConstraints();
	}

}
